<template>
  <page-view class="page-view page-view-container" :title="false">

    <div slot="headerContent">
      <div class="title">权限管理</div>
    </div>

    <a-card v-permission:permission:menu class="s-card">
      <div class="filter">

        <div class="table-page-search-wrapper">
          <a-form layout="inline">
            <a-row :gutter="48">
              <a-col :md="8" :sm="24">
                <a-form-item label="权限编码">
                  <a-input v-model="queryParam.code" placeholder="请输入" />
                </a-form-item>
              </a-col>
              <a-col :md="8" :sm="24">
                <a-form-item label="权限名称">
                  <a-input v-model="queryParam.name" placeholder="请输入" />
                </a-form-item>
              </a-col>
              <a-col :md="8" :sm="24">
                <span class="table-page-search-submitButtons">
                  <a-row :gutter="48">
                    <a-col :md="16">
                      <a-button class="primary-btn" @click="$refs.table.refresh(true)">查询</a-button>
                      <a-button style="margin-left: 8px" @click="resetForm">清除查询</a-button>
                    </a-col>
                    <a-col :md="8">
                      <a-button v-permission:permission:add class="primary-btn" @click="handleCreate()">新建</a-button>
                    </a-col>
                  </a-row>
                </span>
              </a-col>
            </a-row>
          </a-form>
        </div>
      </div>

      <div class="table-container">
        <s-table
          ref="table"
          bordered
          :columns="user && user.permission && user.permission.includes('permission:update') ? columns : columnsBase"
          :data="loadData"
          :show-pagination="false"
          row-key="domain.code"
          hide-on-single-page
          show-total
          show-quick-jumper
          class="pagination-container s-table"
        >
          <span slot="actions" slot-scope="text, record">
            <a-tag v-for="(action, index) in record.actionList" :key="index" @click="handleTagEdit(action)">{{ action.name }}</a-tag>
          </span>

          <span slot="status" slot-scope="text">
            {{ text | statusFilter }}
          </span>

          <span slot="action" slot-scope="text, record">
            <a v-if="record.domain.enabled" class="disabled-link no-padding" href="javascript:;" @click="handleStatus(record)">禁用</a>
            <a v-if="!record.domain.enabled" href="javascript:;" @click="handleStatus(record)">启用</a>
            <a-divider type="vertical" />
            <a @click="handleEdit(record)">编辑</a>
            <a-divider type="vertical" />
            <a-popconfirm
              overlay-class-name="width-unset"
              title="是否要删除此行？"
              @confirm="handleDelete(record)"
            >
              <a class="danger-link no-padding" href="javascript:;">删除</a>
            </a-popconfirm>
            <!-- <a-dropdown>
              <a class="ant-dropdown-link">
                更多 <a-icon type="down" />
              </a>
              <a-menu slot="overlay">
                <a-menu-item>
                  <a v-if="record.domain.enabled" href="javascript:;" @click="handleStatus(record)">禁用</a>
                  <a v-if="!record.domain.enabled" href="javascript:;" @click="handleStatus(record)">启用</a>
                </a-menu-item>
                <a-menu-item>
                  <a-popconfirm
                    overlay-class-name="width-unset"
                    title="是否要删除此行？"
                    @confirm="handleDelete(record)"
                  >
                    <a href="javascript:;">删除</a>
                  </a-popconfirm>
                </a-menu-item>
              </a-menu>
            </a-dropdown> -->
          </span>
        </s-table>

        <a-modal
          v-model="visible"
          title="操作"
          :width="800"
          :destroy-on-close="true"
          @ok="handleOk"
          @cancel="handleCancel"
        >
          <a-form :form="form">

            <a-form-item
              :label-col="labelCol"
              :wrapper-col="wrapperCol"
              label="唯一识别码"
              has-feedback
              validate-status="success"
            >
              <a-input id="no" v-model="mdl.domain.code" placeholder="唯一识别码" />
            </a-form-item>

            <a-form-item
              :label-col="labelCol"
              :wrapper-col="wrapperCol"
              label="权限名称"
              has-feedback
              validate-status="success"
            >
              <a-input id="permission_name" v-model="mdl.domain.name" placeholder="起一个名字" />
            </a-form-item>

            <a-form-item
              :label-col="labelCol"
              :wrapper-col="wrapperCol"
              label="状态"
              has-feedback
            >
              <a-select v-model="mdl.domain.enabled">
                <a-select-option value="true">正常</a-select-option>
                <a-select-option value="false">禁用</a-select-option>
              </a-select>
            </a-form-item>

            <a-divider />

            <a-form-item
              :label-col="labelCol"
              :wrapper-col="wrapperCol"
              label="赋予权限"
              has-feedback
            >
              <a-select
                v-model="mdl.actions"
                style="width: 100%"
                mode="multiple"
                :allow-clear="true"
                @change="selectChange"
              >
                <a-select-option v-for="(action, index) in permissionList" :key="index" :value="action.value">{{ permissonMap[action.value] }}</a-select-option>
              </a-select>
            </a-form-item>

            <div v-if="!isCreated">
              <a-table
                ref="innerTable"
                row-key="id"
                :pagination="false"
                :columns="user && user.permission && user.permission.includes('permission:update') ? mdlColumns : mdlColumnsBase"
                :data-source="extra"
                :loading="memberLoading"
              >
                <template v-for="(col, i) in ['code', 'name', 'method','type','url']" :slot="col" slot-scope="text, record">
                  <a-input
                    v-if="record.editable"
                    :key="col"
                    style="margin: -5px 0"
                    :value="text"
                    :placeholder="columns[i].title"
                    @change="e => handleChange(e.target.value, col,record)"
                  />
                  <template v-else>{{ text }}</template>
                </template>
                <template slot="operation" slot-scope="text, record">
                  <template v-if="record.editable">
                    <span v-if="record.isNew">
                      <a @click="saveRow(record)">添加</a>
                      <a-divider type="vertical" />
                      <a-popconfirm
                        overlay-class-name="width-unset"
                        title="是否要删除此行？"
                        @confirm="remove(record.id)"
                      >
                        <a>删除</a>
                      </a-popconfirm>
                    </span>
                    <span v-else>
                      <a @click="saveRow(record)">保存</a>
                      <a-divider type="vertical" />
                      <a @click="cancel(record.id)">取消</a>
                    </span>
                  </template>
                  <span v-else>
                    <a @click="toggle(record)">编辑</a>
                    <a-divider type="vertical" />
                    <a-popconfirm
                      overlay-class-name="width-unset"
                      title="是否要删除此行？"
                      @confirm="remove(record.id)"
                    >
                      <a>删除</a>
                    </a-popconfirm>
                  </span>
                </template>
              </a-table>
              <a-button v-permission:permission:add style="width: 100%; margin-top: 16px; margin-bottom: 8px" type="dashed" icon="plus" @click="newMember">新增成员</a-button>
            </div>

          </a-form>
        </a-modal>

        <a-modal
          v-model="tagVisible"
          title="操作"
          :width="800"
          :destroy-on-close="true"
          @ok="handleTagOk"
        >
          <a-form :form="tagForm">

            <a-form-item
              :label-col="labelCol"
              :wrapper-col="wrapperCol"
              label="唯一识别码"
              has-feedback
            >
              <a-input id="code" v-model="tagMdl.code" placeholder="唯一识别码" />
            </a-form-item>

            <a-form-item
              :label-col="labelCol"
              :wrapper-col="wrapperCol"
              label="名称"
              has-feedback
            >
              <a-input id="name" v-model="tagMdl.name" placeholder="请输入名称" />
            </a-form-item>

            <a-form-item
              :label-col="labelCol"
              :wrapper-col="wrapperCol"
              label="类型"
              has-feedback
            >
              <a-select v-model="tagMdl.type" default-value="POST">
                <a-select-option value="连接">url</a-select-option>
                <a-select-option value="菜单">menu</a-select-option>
              </a-select>
            </a-form-item>

            <a-form-item
              :label-col="labelCol"
              :wrapper-col="wrapperCol"
              label="方法"
              has-feedback
            >
              <a-select v-model="tagMdl.method" default-value="POST">
                <a-select-option value="GET">GET</a-select-option>
                <a-select-option value="POST">POST</a-select-option>
                <a-select-option value="PUT">PUT</a-select-option>
                <a-select-option value="DELETE">DELETE</a-select-option>
              </a-select>
            </a-form-item>

            <a-form-item
              :label-col="labelCol"
              :wrapper-col="wrapperCol"
              label="url"
              has-feedback
            >
              <a-input id="url" v-model="tagMdl.url" placeholder="请输入连接url" />
            </a-form-item>
          </a-form>
        </a-modal>
      </div>

    </a-card>
  </page-view>
</template>

<script>
import { STable, PageView } from '@/components'
import { mapState } from 'vuex'

const columnsBase = [
  {
    title: '唯一识别码',
    dataIndex: 'domain.code'
  },
  {
    title: '权限名称',
    dataIndex: 'domain.name'
  },
  {
    title: '可操作权限',
    dataIndex: 'actions',
    scopedSlots: { customRender: 'actions' }
  },
  {
    title: '状态',
    dataIndex: 'domain.enabled',
    customRender: (value) => { return value ? '正常' : '禁用' }
  },
  {
    title: '状态',
    dataIndex: 'action',
    scopedSlots: { customRender: 'action' }
  }
]

const mdlColumnsBase = [
  {
    title: '唯一编码',
    dataIndex: 'code',
    width: '15%',
    scopedSlots: { customRender: 'code' }
  },
  {
    title: '名称',
    dataIndex: 'name',
    width: '15%',
    scopedSlots: { customRender: 'name' }
  },
  {
    title: '方法',
    dataIndex: 'method',
    width: '15%',
    scopedSlots: { customRender: 'method' }
  },
  {
    title: '类型',
    dataIndex: 'type',
    width: '15%',
    scopedSlots: { customRender: 'type' }
  },
  {
    title: 'url',
    dataIndex: 'url',
    width: '15%',
    scopedSlots: { customRender: 'url' }
  },
  {
    title: 'operation',
    dataIndex: 'action',
    width: '15%',
    scopedSlots: { customRender: 'operation' }
  }
]

export default {
  name: 'TableList',
  layout: 'basic-layout',
  components: {
    STable,
    PageView
  },
  filters: {
    statusFilter (status) {
      const statusMap = {
        1: '正常',
        2: '禁用'
      }
      return statusMap[status]
    }
  },
  data () {
    return {
      memberLoading: false,
      visible: false,
      tagVisible: false,
      labelCol: {
        xs: { span: 24 },
        sm: { span: 5 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      },
      form: null,
      tagForm: null,
      isCreated: false,
      mdl: {
        domain: {},
        resources: {}
      },
      tagMdl: {
        id: '',
        code: '',
        name: '',
        type: 'url',
        method: 'POST',
        url: ''
      },
      // table
      extra: [],
      tmpAction: '',
      // 高级搜索 展开/关闭
      advanced: false,
      // 查询参数
      queryParam: {},
      // 表头
      columnsBase,
      columns: [...columnsBase
      // , {
      //   title: '操作',
      //   width: '220px',
      //   dataIndex: 'action',
      //   scopedSlots: { customRender: 'action' }
      // }
      ],
      mdlColumnsBase,
      mdlColumns: [...mdlColumnsBase
      // , {
      //   title: '操作',
      //   key: 'action',
      //   scopedSlots: { customRender: 'operation' }
      // }
      ],
      // 向后端拉取可以用的操作列表
      permissionList: null,
      permissionMap: null,
      permissionData: null,
      // 加载数据方法 必须为 Promise 对象
      loadData: parameter => {
        return this.$resourceApi.getByPage(parameter.pageNo, parameter.pageSize, { ...this.queryParam }).then(res => {
          const result = res.data
          this.permissionData = result
          result.map(permission => {
            permission.actionList = []
            permission.actions = []
            permission.extra.forEach(item => {
              item.editable = false
            })
            permission.resources.forEach(resource => {
              permission.actionList.push({ id: resource.id, name: resource.name })
              const key = resource.code.substr(resource.code.indexOf(':') + 1, resource.size)
              permission.actions.push(key)
            })
            permission.extra.forEach(extra => {
              permission.actionList.push({ id: extra.id, name: extra.name })
            })
            return permission
          })
          return res
        })
      },

      selectedRowKeys: [],
      selectedRows: []
    }
  },

  computed: {
    ...mapState({
      user: state => state.auth.user
    })
  },

  watch: {
    /*
      'selectedRows': function (selectedRows) {
        this.needTotalList = this.needTotalList.map(item => {
          return {
            ...item,
            total: selectedRows.reduce( (sum, val) => {
              return sum + val[item.dataIndex]
            }, 0)
          }
        })
      }
      */
  },
  created () {
    this.loadPermissionList()
  },
  methods: {
    loadPermissionList () {
      // permissionList
      new Promise(resolve => {
        const data = [
          { name: '新增', value: 'add', defaultChecked: false },
          { name: '查询', value: 'get', defaultChecked: false },
          { name: '修改', value: 'update', defaultChecked: false },
          { name: '列表', value: 'list', defaultChecked: false },
          { name: '删除', value: 'delete', defaultChecked: false },
          { name: '导入', value: 'import', defaultChecked: false },
          { name: '导出', value: 'export', defaultChecked: false }
        ]
        setTimeout(resolve(data), 1500)
      }).then(res => {
        this.permissionList = res
        this.permissonMap = {}
        res.forEach(item => {
          this.permissonMap[item.value] = item.name
        })
      })
    },
    handleTagEdit (action) {
      this.tagVisible = true
      const permissionData = this.permissionData
      var permission
      permissionData.filter(item => {
        const resources = item.resources
        const extra = item.extra
        var flag = false
        resources.map(resource => {
          if (!flag && resource.id === action.id) {
            flag = true
            permission = resource
          }
        })
        extra.map(ext => {
          if (!flag && ext.id === action.id) {
            flag = true
            permission = ext
          }
        })
      })
      this.tagMdl = permission
    },
    handleEdit (record) {
      this.mdl = record
      this.tmpAction = this.mdl.actions
      this.mdl.domain.enabled = record.domain.enabled === true ? 'true' : 'false'
      this.extra = record.extra
      this.isCreated = false
      this.visible = true
    },
    handleCreate () {
      this.tmpAction = []
      this.isCreated = true
      this.visible = true
      this.mdl = {
        domain: {},
        resources: {}
      }
    },
    newMember () {
      const length = this.extra.length
      this.extra.push({
        id: length === 0 ? '1' : (parseInt(this.extra[length - 1].id) + 1).toString(),
        code: this.mdl.domain.code + ':',
        name: '',
        type: 'url',
        method: 'POST',
        url: '/' + this.mdl.domain.code + '/',
        editable: true,
        isNew: true
      })
    },
    async remove (id) {
      const that = this
      await that.$resourceApi.delOne(id).then(() => {
        const newData = this.extra.filter(item => item.id !== id)
        this.extra = newData
      })
    },
    async saveRow (record) {
      const that = this
      this.memberLoading = true
      const { code, name, method, url } = record
      if (!code || !name || !method || !url) {
        this.memberLoading = false
        this.$message.error('请填写完整成员信息。')
        return
      }
      if (record.isNew) {
        record.createdBy = this.user && this.user.id || ''
        record.updatedBy = this.user && this.user.id || ''
        await that.$resourceApi.addOne(this.mdl.domain.id, record).then((res) => {
          const target = that.extra.filter(item => item.code === code)[0]
          target.editable = false
          target.isNew = false
          that.memberLoading = false
          record.id = res.data.id
        })
      } else {
        await that.$resourceApi.updateOne(record.id, record).then(() => {
          const target = that.extra.filter(item => item.code === code)[0]
          target.editable = false
          target.isNew = false
          that.memberLoading = false
        })
      }
    },
    toggle (record) {
      this.memberLoading = true
      record.editable = true
      this.memberLoading = false
    },
    getRowByKey (id, newData) {
      const data = this.extra
      return (newData || data).filter(item => item.id === id)[0]
    },
    cancel (id) {
      this.memberLoading = true
      const target = this.extra.filter(item => item.id === id)[0]
      target.editable = false
      this.memberLoading = false
    },
    async handleOk () {
      const params = {
        code: this.mdl.domain.code,
        name: this.mdl.domain.name,
        enabled: this.mdl.domain.enabled,
        type: 'resource',
        actions: this.mdl.actions
      }
      if (this.isCreated) {
        params.createdBy = this.user && this.user.id || ''
        params.updatedBy = this.user && this.user.id || ''
        await this.$resourceApi.add(params).then(res => {
          this.$refs.table.refresh(true)
          this.visible = false
        })
      } else {
        await this.$resourceApi.update(this.mdl.domain.id, params).then(res => {
          this.$refs.table.refresh(true)
          this.visible = false
        })
      }
    },
    async handleTagOk () {
      const params = {
        code: this.tagMdl.code,
        name: this.tagMdl.name,
        type: this.tagMdl.type,
        method: this.tagMdl.method,
        url: this.tagMdl.url
      }
      await this.$resourceApi.updateOne(this.tagMdl.id, params).then(() => {
        this.$refs.table.refresh(false)
        this.tagVisible = false
      })
    },
    handleCancel () {
      this.mdl.actions = this.tmpAction
    },
    async handleDelete (record) {
      await this.$resourceApi.del(record.domain.id).then(res => {
        this.$refs.table.refresh(true)
      })
    },
    onChange (selectedRowKeys, selectedRows) {
      this.selectedRowKeys = selectedRowKeys
      this.selectedRows = selectedRows
    },
    selectChange () {
      this.memberLoading = true
      this.memberLoading = false
    },
    toggleAdvanced () {
      this.advanced = !this.advanced
    },
    handleStatus (record) {
      const that = this
      const params = {
        id: record.domain.id,
        enabled: !record.domain.enabled
      }
      this.$domainApi.toggle(params).then(res => {
        that.$refs.table.refresh(true)
      })
    },
    handleChange (value, column, record) {
      // console.log(value, column)
      // this.extra[record.id] = record
      // this.extra[record.id][column] = value
      record[column] = value
      // console.log(this.extra)
    },
    resetForm () {
      this.queryParam = {}
    }
  }
}
</script>

<style lang="less" scoped>
.table-page-search-wrapper {
  .ant-form {
    .ant-row {
      .table-page-search-submitButtons,
      .ant-row.ant-form-item {
        margin-bottom: 0;
      }
    }
  }
}
</style>
